}; printk("\n");
printk(" blk_ring: 0x%lx\n", si->blk_ring);
#endif
- printk(" dom_id: %d\n", si->dom_id);
+ printk(" dom_id: %ld\n", si->dom_id);
printk(" flags: 0x%lx\n", si->flags);
printk(" cmd_line: %s\n", si->cmd_line ? (const char *)si->cmd_line : "NULL");
* Stop/pickle callback handling.
*/
+#include <asm/suspend.h>
+
static void stop_task(void *unused)
{
/* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
extern void blkdev_suspend(void);
extern void blkdev_resume(void);
+ unsigned long *pfn_to_mfn_frame_list = NULL;
+ suspend_record_t *suspend_record = NULL;
struct net_device *dev;
char name[6];
- int i;
+ int i, j;
+
+ if ( (pfn_to_mfn_frame_list = (unsigned long *)__get_free_page(GFP_KERNEL))
+ == NULL )
+ goto out;
+ if ( (suspend_record = (suspend_record_t *)__get_free_page(GFP_KERNEL))
+ == NULL )
+ goto out;
+
+ suspend_record->pfn_to_mfn_frame_list =
+ virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
+ suspend_record->nr_pfns = max_pfn;
+
+ j = 0;
+ for ( i = 0; i < max_pfn; i += (PAGE_SIZE / sizeof(unsigned long)) )
+ pfn_to_mfn_frame_list[j++] =
+ virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
rtnl_lock();
for ( i = 0; i < 10; i++ )
HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
clear_fixmap(FIX_SHARED_INFO);
- HYPERVISOR_stop();
+ memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info));
+
+ HYPERVISOR_stop(virt_to_machine(suspend_record) >> PAGE_SHIFT);
+
+ memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info));
set_fixmap(FIX_SHARED_INFO, start_info.shared_info);
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
dev_open(dev);
}
rtnl_unlock();
+
+ out:
+ if ( pfn_to_mfn_frame_list != NULL )
+ free_page((unsigned long)pfn_to_mfn_frame_list);
+ if ( suspend_record != NULL )
+ free_page((unsigned long)suspend_record);
}
static struct tq_struct stop_tq;
return ret;
}
-static inline int HYPERVISOR_stop(void)
+static inline int HYPERVISOR_stop(unsigned long srec)
{
int ret;
+ /* NB. On suspend, control software expects a suspend record in %esi. */
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_stop) );
+ "b" (SCHEDOP_stop), "S" (srec) : "memory" );
return ret;
}